package com.plusmoney.approval.customer;

import com.alibaba.fastjson.JSONObject;
import com.mp.approvalreq.entity.*;
import com.mp.approvalreq.entity.common.Constants;
import com.mp.approvalreq.entity.dto.ExchangeTemplateDTO;
import com.mp.approvalreq.entity.dto.RedPointDTO;
import com.mp.approvalreq.entity.message.RequestTimeMsg;
import com.mp.approvalreq.entity.message.TemplateMsg;
import com.mp.approvalreq.service.*;
import com.mp.approvalreq.util.MQApprovalUtils;
import com.mp.approvalreq.util.MailUtils;
import com.mp.checkin.util.EmailUtils;
import com.plusmoney.exception.RpcServerLogicalException;
import com.plusmoney.mq.MQUtils;
import com.plusmoney.redis.RedisUtils;
import com.plusmoney.util.Utils;
import com.qq.tars.client.util.ServantUtils;
import org.apache.log4j.NDC;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;

import java.util.List;


public class ApprovalListener implements MessageListenerConcurrently {

    private static final Logger logger = LoggerFactory.getLogger(ApprovalListener.class);

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
        try {
            Jedis jedis = RedisUtils.getJedis();

            for (MessageExt msg : list) {
                int retry = 3;
                NDC.push(Utils.getNDCMessage());

                logger.info("msgId:{}, tags:{}, keys:{}, body:{}",
                 msg.getMsgId(), msg.getTags(), msg.getKeys(), new String(msg.getBody()));

                String redisKey = RedisUtils.getKey(Constants.MQ_GROUP_NAME, Constants.MQ_APPROVAL_TOPIC, msg.getMsgId());
                if (!MQUtils.isNewMessage(jedis, redisKey)) {
                    logger.info("消息重复");
                    NDC.pop();
                    continue;
                }
                try {
                    consumeMsg(msg);
                } catch (Throwable e) {
                    logger.error(e.getMessage(), e);
                    MailUtils.sendMail(MailUtils.EMAIL, "审批消费者出错", e.getMessage());
                    logger.info("重试次数:{}", --retry);
                    if (retry > 0) {
                        consumeMsg(msg);
                        EmailUtils.sendErrorMail("审批重新消费成功", new String(msg.getBody()));
                    }
                } finally {
                    NDC.pop();
                }


            }

            RedisUtils.close(jedis);

            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
            throw new RpcServerLogicalException(1, "报错了");
        }
    }

    private void consumeMsg(MessageExt msg) throws Throwable {
        switch (msg.getTags()) {
            case Constants.MQ_TAGS_UPDATE_TEMPLATE: {
                TemplateMsg templateMsg = JSONObject.parseObject(msg.getBody(), TemplateMsg.class);
                MQApprovalUtils mqApprovalUtils = new MQApprovalUtils();
                mqApprovalUtils.initSelectApprovalService(ServantUtils.getObject(SelectApprovalServicePrx.class));
                mqApprovalUtils.initApprovalOperateService(ServantUtils.getObject(ApprovalOperateServicePrx.class));
                mqApprovalUtils.switchTemplateTempCc(templateMsg);

                break;
            }
            case Constants.MQ_TAGS_DAYS_OFF_TIMES: {
                RequestTimeMsg requestTimeMsg = JSONObject.parseObject(msg.getBody(), RequestTimeMsg.class);
                MQApprovalUtils mqApprovalUtils = new MQApprovalUtils();
                mqApprovalUtils.initCommontApprovalService(ServantUtils.getObject(CommontApprovalServicePrx.class));
                mqApprovalUtils.recordDaysOffTime(requestTimeMsg);
                MQApprovalUtils.sendHrCalculateDaysOff(requestTimeMsg.getCompanyId(), requestTimeMsg.getCompanyInfoId());
                break;
            }
            case Constants.MQ_TAGS_FILL_OUTDOOR_ADDRESS:
                Outdoor outdoor = JSONObject.parseObject(msg.getBody(), Outdoor.class);
                CommontApprovalServicePrx commontApprovalServicePrx = ServantUtils.getObject(CommontApprovalServicePrx.class);
                commontApprovalServicePrx.fillOutdoorAddress(outdoor);
                break;
            case Constants.MQ_TAGS_OUT_SIGN_INFO: {
                OutSignInfo outSignInfo = JSONObject.parseObject(msg.getBody(), OutSignInfo.class);
                MQApprovalUtils mqApprovalUtils = new MQApprovalUtils();
                mqApprovalUtils.initCommontApprovalService(ServantUtils.getObject(CommontApprovalServicePrx.class));
                mqApprovalUtils.recordOutSignInfo(outSignInfo);
                break;
            }
            case Constants.MQ_TARS_BUSINESS_TRIP_SIGN_INFO:
                handleBusinessTripSignInfo(msg);
                break;
            case Constants.MQ_INVENTORY_REPLACE_APPROVER:
                replaceApproveUser(msg);
                break;
            case Constants.MQ_TAG_CLEAR_RED_POINT:
                clearRedPoint(msg);
                break;
            case Constants.MQ_TAG_APPROVAL_MODIFY:
                addModifyRecords(msg);
                break;

            //入口 审批关联记录
            case Constants.MQ_TAG_APPROVAL_MODIFY_RELATE:
                modifyApprovalRelate(msg);
                break;
            default:
                break;
        }
    }

    private void modifyApprovalRelate(MessageExt msg) throws Throwable {
        RelateHistory relateHistory = JSONObject.parseObject(new String(msg.getBody()), RelateHistory.class);
        Integer modifyType = "Link".equalsIgnoreCase(msg.getKeys()) ? 1 : 0;
        relateHistory.setModifyType(modifyType);
        logger.info("添加关联记录:{}", relateHistory.getObjectId());
        RequestServicePrx requestServicePrx = ServantUtils.getObject(RequestServicePrx.class);
        requestServicePrx.modifyApprovalRelate(relateHistory);
    }

    private void addModifyRecords(MessageExt msg) throws Throwable {
        Template template = JSONObject.parseObject(new String(msg.getBody()), Template.class);
        logger.info("添加修改记录:{}", template.getTemplateId());
        TemplateServicePrx templateServicePrx = ServantUtils.getObject(TemplateServicePrx.class);
        templateServicePrx.addModifyRecord(template);
    }

    private void clearRedPoint(MessageExt msg) throws Throwable {
        RedPointDTO redPointDTO = JSONObject.parseObject(new String(msg.getBody()), RedPointDTO.class);
        RedPointServicePrx redPointServicePrx = ServantUtils.getObject(RedPointServicePrx.class);
        redPointServicePrx.clearRedPoint(redPointDTO);
    }

    private void replaceApproveUser(MessageExt msg) {
        try {
            JSONObject jo = JSONObject.parseObject(new String(msg.getBody()));
            ExchangeTemplateDTO exchangeTemplateDTO = new ExchangeTemplateDTO();
            exchangeTemplateDTO.setCompanyId(jo.getInteger("companyId"));
            exchangeTemplateDTO.setQuitContactId(jo.getInteger("contactId"));
            exchangeTemplateDTO.setReceiveContactId(jo.getInteger("replaceContactId"));
            exchangeTemplateDTO.setProjectIds(jo.getString("projectIds"));

            ApprovalOperateServicePrx approvalOperateServicePrx = ServantUtils.getObject(ApprovalOperateServicePrx.class);
            approvalOperateServicePrx.exchangeGeneralRequestFlows(exchangeTemplateDTO);


        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
            MailUtils.sendMail(MailUtils.EMAIL, "替换审批人出错", e.getMessage());
        }
    }

    private void handleBusinessTripSignInfo(MessageExt msg) {
        try {
            BusinessTripSignInfo businessTripSignInfo = JSONObject.parseObject(new String(msg.getBody()), BusinessTripSignInfo.class);
            logger.info(businessTripSignInfo.toString());
            CommontApprovalServicePrx commontApprovalServicePrx = ServantUtils.getObject(CommontApprovalServicePrx.class);
            commontApprovalServicePrx.recordAddressOfBusinessTrip(businessTripSignInfo);
        } catch (Throwable e) {
            logger.error(e.getMessage(), e);
            MailUtils.sendMail(MailUtils.EMAIL, "~", e.getMessage());
        }
    }

}
